#include "RoughReflectiveMaterial.h"
#include "Integrator.h"

RoughReflectiveMaterial::RoughReflectiveMaterial(Double roughness, Float reflectiveness, int sampleCount) : ReflectiveMaterial(reflectiveness) {
	this->roughness = roughness;
	this->sampleCount = sampleCount;
}

RoughReflectiveMaterial::RoughReflectiveMaterial(shared_ptr<Material> material, Double roughness, Float reflectiveness, int sampleCount) : ReflectiveMaterial(material, reflectiveness) {
	this->roughness = roughness;
	this->sampleCount = sampleCount;
}

void RoughReflectiveMaterial::setSampleCount(int sampleCount) {
	this->sampleCount = sampleCount;
}

Color RoughReflectiveMaterial::shade(const Scene * scene, const Ray & ray, const IntersectResult &intersect, const TraceState & traceState) const {
	Vector3 r = reflect(ray.dir, intersect.normal);
	Color color;
	Vector3 random;
	Ray reflectedRay(intersect.position);
	for (int i = 0; i < sampleCount; i++) {
		random = randomPointInUnitSphere();
		random *= roughness;
		reflectedRay.dir = (r + random);
		if (reflectedRay.dir * intersect.normal <= 0) continue;
		reflectedRay.dir.normalize();
		color += scene->getIntegrator()->Li(scene, reflectedRay, traceState);
	}
	color *= strength / sampleCount;
	return material ? color *= material->shade(scene, ray, intersect, traceState) : color;
}